import java.io.*;
import java.util.Scanner;

public class Main {
    private static boolean isConversion;

    public static void main(String[] args) {
        System.err.println("欢迎使用由JackiePenghe开发的进制转换工具！");
        Scanner scanner = new Scanner(System.in);
        String hexString = String.format("%08X", Long.parseLong("1"));
        System.out.println("请选择转换方法：");
        System.out.println("1. 10进制数据源");
        System.out.println("2. 16进制数据源");
        System.out.print("请选择转换方法(输入quit或exit退出程序)：");
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            }
            switch (s) {
                case "1":
                    decimalToHex(scanner);
                    break;
                case "2":
                    hexToDecimal(scanner);
                    break;
                default:
                    System.out.println("输入错误，请重新输入！");
                    System.out.println("1. 10进制转换为16进制");
                    System.out.println("2. 16进制转换为10进制");
                    System.out.print("请选择转换方法(输入quit或exit退出程序)：");
                    break;
            }
        }

    }

    /**
     * 16进制转换为10进制
     *
     * @param scanner 接收输入
     */
    private static void hexToDecimal(Scanner scanner) {
        System.out.println("请输入文本文件路径：（路径为全路径，txt文件，回车区分每个十六进制，quit或exit退出程序）");
        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            }
            if (isConversion) {
                System.out.println("正在处理上一个文件，请稍等");
                continue;
            }
            isConversion = true;
            System.out.println("正在转换，请稍后");
            startHexToDecimalConvertThread(s);
        }
    }

    //    E:\Users\pengh\Desktop\新建 文本文档.txt
    private static void startHexToDecimalConvertThread(String filePath) {
        new Thread(() -> {
            FileReader fileReader = null;
            BufferedReader bufferedReader = null;
            try {
                fileReader = new FileReader(filePath);
                bufferedReader = new BufferedReader(fileReader);
                while (true) {
                    String line = bufferedReader.readLine();
                    if (line == null) {
                        break;
                    }
                    convertHexDataAndWriteToFile(line, filePath);
                }
            } catch (FileNotFoundException e) {
                System.out.println("文件不存在");
            } catch (FileWriteException e) {
                System.out.println(e.getMessage());
            } catch (IOException e) {
                System.out.println("数据转换异常，请检查文件内容是否合法");
            } finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        System.out.println("关闭文件读取流失败");
                    }
                }
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        System.out.println("关闭文件读取流失败");
                    }
                }
                isConversion = false;
                System.out.println("转换处理结束,可继续输入文件路径转换,输入exit或quit退出程序");
            }
        }).start();
    }

    private static void convertHexDataAndWriteToFile(String line, String sourceFilePath) throws FileWriteException {
        String hexSource = line.trim();
        if (hexSource.length() > 8) {
            throw new FileWriteException("十六进制字符串长度不能超过8个字符");
        }
        long sourceDecimal;
        try {
            sourceDecimal = Long.parseLong(hexSource, 16);
        } catch (NumberFormatException e) {
            throw new FileWriteException("十六进制字符串格式错误,转换为十进制失败");
        }
        String hexRevert = revertData(hexSource);
        long revertDecimal;
        try {
            revertDecimal = Long.parseLong(hexRevert, 16);
        } catch (NumberFormatException e) {
            throw new FileWriteException("翻转后的十六进制字符串格式错误,转换为十进制失败 hexRevert = " + hexRevert);
        }
        StringBuilder sourceDecimalStr = new StringBuilder(String.valueOf(sourceDecimal));
        if (sourceDecimalStr.length() < 10) {
            for (int i = 0; i < 10 - sourceDecimalStr.length(); i++) {
                sourceDecimalStr.insert(0, "0");
            }
        }
        StringBuilder revertDecimalStr = new StringBuilder(String.valueOf(revertDecimal));
        if (revertDecimalStr.length() < 10) {
            for (int i = 0; i < 10 - revertDecimalStr.length(); i++) {
                revertDecimalStr.insert(0, "0");
            }
        }
        File file = new File(sourceFilePath);
        String name = file.getName();
        String[] split = name.split("\\.");
        File parentFile = file.getParentFile();
        File newFile = new File(parentFile, split[0] + "-revert.txt");
        try {
            FileWriter fileWriter = new FileWriter(newFile, true);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
            bufferedWriter
                    .append("源十六进制：")
                    .append(hexSource)
                    .append("\t")
                    .append("源10进制：")
                    .append(sourceDecimalStr.toString())
                    .append("\t")
                    .append("逆序十六进制：")
                    .append(hexRevert)
                    .append("\t")
                    .append("逆序10进制：")
                    .append(revertDecimalStr.toString())
                    .append("\n")
                    .flush();
            fileWriter.close();
            bufferedWriter.close();
        } catch (Exception e) {
            throw new FileWriteException("写入转换后的数据失败");
        }
    }

    /**
     * 10进制转换为16进制
     *
     * @param scanner 接收输入
     */
    private static void decimalToHex(Scanner scanner) {
        System.out.println("请输入文本文件路径：（路径为全路径，txt文件，回车区分每个十进制，quit或exit退出程序）");

        while (true) {
            boolean nextLine = scanner.hasNextLine();
            if (!nextLine) {
                continue;
            }
            String s = scanner.nextLine();
            if (s.equalsIgnoreCase("exit") || s.equalsIgnoreCase("quit")) {
                break;
            }
            if (isConversion) {
                System.out.println("正在处理上一个文件，请稍等");
                continue;
            }
            isConversion = true;
            System.out.println("正在转换，请稍后");
            startDecimalToHexConvertThread(s);
        }
    }

    private static void startDecimalToHexConvertThread(String filePath) {
        new Thread(() -> {
            FileReader fileReader = null;
            BufferedReader bufferedReader = null;
            try {
                fileReader = new FileReader(filePath);
                bufferedReader = new BufferedReader(fileReader);
                while (true) {
                    String line = bufferedReader.readLine();
                    if (line == null) {
                        break;
                    }
                    convertDecimalDataAndWriteToFile(line, filePath);
                }
            } catch (FileNotFoundException e) {
                System.out.println("文件不存在");
            } catch (FileWriteException e) {
                System.out.println("写入转换后的数据失败");
            } catch (IOException e) {
                System.out.println("数据转换异常，请检查文件内容是否合法");
            } finally {
                if (fileReader != null) {
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        System.out.println("关闭文件读取流失败");
                    }
                }
                if (bufferedReader != null) {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        System.out.println("关闭文件读取流失败");
                    }
                }
                isConversion = false;
                System.out.println("转换处理结束,可继续输入文件路径转换,输入exit或quit退出程序");
            }
        }).start();
    }

    /**
     * 翻转数据并写入到新的文件
     *
     * @param line           内容
     * @param sourceFilePath 源文件路径
     */
    private static void convertDecimalDataAndWriteToFile(String line, String sourceFilePath) throws FileWriteException {
        String trim = line.trim();
        String hexString = String.format("%08X", Long.parseLong(trim));
        String sourceHex = hexString.toUpperCase();
        String result;
        try {
            result = revertData(sourceHex);
        } catch (NumberFormatException e) {
            throw new FileWriteException("十六进制字符串翻转失败");
        }
        File file = new File(sourceFilePath);
        String name = file.getName();
        String[] split = name.split("\\.");
        File parentFile = file.getParentFile();
        File newFile = new File(parentFile, split[0] + "-revert.txt");
        try {
            FileWriter fileWriter = new FileWriter(newFile, true);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
            bufferedWriter
                    .append("正序：")
                    .append(sourceHex)
                    .append("\t")
                    .append("逆序：")
                    .append(result)
                    .append("\n")
                    .flush();
            fileWriter.close();
            bufferedWriter.close();
        } catch (Exception e) {
            throw new FileWriteException("写入转换后的数据失败");
        }

    }

    private static String revertData(String trim) throws NumberFormatException {
        byte[] bytes = hexStrToByteArray(trim);
        byte[] result = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            result[bytes.length - i - 1] = bytes[i];
        }
        String byteArrayString = byteArrayToHexStr(result);
        return byteArrayString.replace(" ", "");
    }

    /**
     * byteArray字符串转换为Byte值
     *
     * @param src Byte字符串，每个Byte之间没有分隔符
     * @return byte[]
     */
    public static byte[] hexStrToByteArray(String src) throws NumberFormatException {
        int m, n;
        int l = src.length() / 2;
        System.out.println(l);
        byte[] ret = new byte[l];
        for (int i = 0; i < l; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int integer = Integer.decode("0x" + src.substring(i * 2, m) + src.substring(m, n));
            ret[i] = (byte) integer;
        }
        return ret;
    }

    /**
     * byteArray转换成十六进制字符串
     *
     * @param byteArray byte数组
     * @return String 每个Byte值之间空格分隔
     */
    public static String byteArrayToHexStr(byte[] byteArray) {
        String stmp;
        StringBuilder sb = new StringBuilder();
        for (byte aByte : byteArray) {
            stmp = Integer.toHexString(aByte & 0xFF);
            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
            sb.append(" ");
        }
        return sb.toString().toUpperCase().trim();
    }
}
